package com.itlong.cloud.controller.home;

import com.itlong.cloud.POJO.DTO.app.property.app.PropertyAppAlarmDTO;
import com.itlong.cloud.POJO.DTO.app.property.app.PropertyAppInspectDTO;
import com.itlong.cloud.POJO.PO.PropertyInspectPointInfoPO;
import com.itlong.cloud.POJO.PO.PropertyInspectRecordPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.property.app.PropertyAppInspectLineInfoVO;
import com.itlong.cloud.POJO.VO.app.property.app.PropertyAppInspectRecordDetailVO;
import com.itlong.cloud.POJO.VO.app.property.app.PropertyAppInspectInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyUserCacheVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyAppErrorCodeEnum;
import com.itlong.cloud.inspect.IPropertyAppInspectServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.propertyapp.IPropertyAppUserInfoServiceClient;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      物业app巡检模块控制器
 * </desc>
 *
 * @createDate2020/1/7
 **/
@RestController
@RequestMapping("/home")
@RefreshScope
public class PropertyAppInspectController extends BaseController {

    @Value("${" + PlatformConstants.PROPERTY_APP_USER_TOKEN_KEY + "}")
    public String PROPERTY_APP_USER_TOKEN_KEY;

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    private IPropertyAppInspectServiceClient iPropertyAppInspectServiceClient;

    @Autowired
    private IPropertyAppUserInfoServiceClient iPropertyAppUserInfoServiceClient;

    /**
     * <desc>
     *      巡检计划列表
     * </desc>
     *
     * @param token
     * @param projectId
     * @return
     * @Author Zhu.yj
     * @createDate  2020/1/6
     */
    @ResponseBody
    @RequestMapping(value = "inspectPlanList",method = RequestMethod.POST)
    public Object inspectPlanList(String token, String projectId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            PropertyUserCacheVO propertyUserCacheVO = iPropertyAppUserInfoServiceClient.retrieve(token);
            if (propertyUserCacheVO.getCardLevel() == 1){
                return new MessageVO(PropertyAppErrorCodeEnum.USER_HAVE_NO_INSPECT_PLAN.getErrorCode());
            }
            List<PropertyAppInspectInfoVO> propertyAppInspectInfoVOS = iPropertyAppInspectServiceClient.getInspectPlanList(propertyUserCacheVO.getUserId(),projectId);
            if (propertyAppInspectInfoVOS == null || propertyAppInspectInfoVOS.size() == 0){
                return new MessageVO(PropertyAppErrorCodeEnum.ACCOUNT_HAVE_NO_INSPECT_PLAN.getErrorCode());
            }
            List<Map<String, Object>> resultMapList = new ArrayList<>();
            for (PropertyAppInspectInfoVO propertyAppInspectInfoVO : propertyAppInspectInfoVOS){
                Map<String,Object> resultMap = SqlUtil.convertBeanToMapParams(propertyAppInspectInfoVO);
                resultMap.remove("inspectPointId");
                resultMap.remove("inspectPointName");
                resultMap.remove("deviceUnique");
                resultMapList.add(resultMap);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),resultMapList);
        }catch (Exception e){
            throw new DataAccessException("【物业APP-首页-巡检计划列表inspectPlanList】获取巡检计划列表失败",e);
        }
    }

    /**
     * <desc>
     *      添加报警详细信息
     * </desc>
     *
     * @param propertyAppAlarmDTO 物业app报警信息DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2020/1/7
     */
    @ResponseBody
    @RequestMapping(value = "/updatePoliceCallDetail",method = RequestMethod.POST)
    public Object updatePoliceCallDetail(PropertyAppAlarmDTO propertyAppAlarmDTO,HttpServletRequest request){
        try{
            propertyAppAlarmDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAppAlarmDTO.class,request);
            if (propertyAppAlarmDTO == null || StringUtils.isBlank(propertyAppAlarmDTO.getProjectId()) || StringUtils.isBlank(propertyAppAlarmDTO.getInspectPlanId())
                    || StringUtils.isBlank(propertyAppAlarmDTO.getCallAddress()) ||StringUtils.isBlank(propertyAppAlarmDTO.getContent())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (propertyAppAlarmDTO.getCallAddress().length() > 30){
                return new MessageVO(PropertyAppErrorCodeEnum.ALARM_POSITION_TOO_LONG.getErrorCode());
            }
            PropertyUserCacheVO propertyUserCacheVO = iPropertyAppUserInfoServiceClient.retrieve(propertyAppAlarmDTO.getToken());
            String uploadInfo = "";
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            // 是否是带文件上传的表单
            if (isMultipart) {
                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                Map<String,MultipartFile> multipartFileMap = multipartRequest.getFileMap();
                if (multipartFileMap != null && !multipartFileMap.isEmpty()){
                    for (String fileKey : multipartFileMap.keySet()) {
                        List<MultipartFile> fileList = multipartRequest.getFiles(fileKey);
                        for (MultipartFile mediaFile : fileList) {
                            String fileName = mediaFile.getOriginalFilename();
                            InputStream fileStream = mediaFile.getInputStream();
                            String uploadFileUrl = this.uploadFile(fileStream, fileName);
                            if ("".equals(uploadInfo)) {
                                uploadInfo = uploadFileUrl;
                            } else {
                                uploadInfo = uploadInfo + "," + uploadFileUrl;
                            }
                        }
                    }
                }
            }
            propertyAppAlarmDTO.setAdminPhone(propertyUserCacheVO.getPhoneNum());
            propertyAppAlarmDTO.setUserId(propertyUserCacheVO.getUserId());
            propertyAppAlarmDTO.setImageUrl(uploadInfo);
            iPropertyAppInspectServiceClient.savePoliceCallDetail(propertyAppAlarmDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业APP-首页保存报警详细信息updatePoliceCallDetail】添加报警详细信息失败",e);
        }
    }

    /**
     * <desc>
     *      提交巡检详情
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/01/08
     */
    @ResponseBody
    @PostMapping(path = "updateInspectPointDetail")
    public Object updateInspectPointDetail(HttpServletRequest request){
        try {
            PropertyAppInspectDTO propertyAppInspectDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAppInspectDTO.class, request);
            if (propertyAppInspectDTO == null || StringUtils.isBlank(propertyAppInspectDTO.getInspectPlanId()) || StringUtils.isBlank(propertyAppInspectDTO.getInspectPointNum())
                    || StringUtils.isBlank(propertyAppInspectDTO.getInspectPointName()) || StringUtils.isBlank(propertyAppInspectDTO.getInspectTime())
                    || StringUtils.isBlank(propertyAppInspectDTO.getContent()) || StringUtils.isBlank(propertyAppInspectDTO.getToken())
                    || StringUtils.isBlank(propertyAppInspectDTO.getInspectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            PropertyUserCacheVO userCacheVO = iPropertyAppUserInfoServiceClient.retrieve(propertyAppInspectDTO.getToken());
            if (userCacheVO == null) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            // 检验巡检点的合理性
            PropertyInspectPointInfoPO propertyInspectPointInfoPO = iPropertyAppInspectServiceClient.getInspectPointByNum(propertyAppInspectDTO);
            if (propertyInspectPointInfoPO == null) {
                return new MessageVO(PropertyAppErrorCodeEnum.INSPECT_POINT_EXIST_ERROR.getErrorCode());
            }
            if (!propertyAppInspectDTO.getInspectPlanId().equals(propertyInspectPointInfoPO.getInspectPlanId())) {
                return new MessageVO(PropertyAppErrorCodeEnum.INSPECT_POINT_EXIST_ERROR.getErrorCode(), "该巡检点编号不属于该巡检计划");
            }
            if (propertyInspectPointInfoPO.getInspectPlanStatus() == 2) {
                return new MessageVO(PropertyAppErrorCodeEnum.INSPECT_POINT_EXIST_ERROR.getErrorCode(), "该巡检计划已被禁用");
            }
            if (propertyInspectPointInfoPO.getStatus() == 2) {
                return new MessageVO(PropertyAppErrorCodeEnum.INSPECT_POINT_EXIST_ERROR.getErrorCode(), "该巡检点编号已被禁用");
            }
            PropertyInspectRecordPO propertyInspectRecordPO = new PropertyInspectRecordPO();
            propertyInspectRecordPO.setProjectId(propertyAppInspectDTO.getProjectId());
            propertyInspectRecordPO.setInspectPlanId(propertyAppInspectDTO.getInspectPlanId());
            propertyInspectRecordPO.setInspectLineId(propertyInspectPointInfoPO.getInspectLineId());
            propertyInspectRecordPO.setInspectPointId(propertyInspectPointInfoPO.getInspectPointId());
            propertyInspectRecordPO.setInspectAreaId(propertyInspectPointInfoPO.getInspectAreaId());
            propertyInspectRecordPO.setUserId(userCacheVO.getUserId());
            Date inspectTime = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(propertyAppInspectDTO.getInspectTime());
            propertyInspectRecordPO.setInspectTime(inspectTime);
            propertyInspectRecordPO.setRemark(propertyAppInspectDTO.getContent());
            // 上传文件
            String uploadInfo = "";
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            // 是否是带文件上传的表单
            if (isMultipart) {
                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                Map<String,MultipartFile> multipartFileMap = multipartRequest.getFileMap();
                if (multipartFileMap != null && !multipartFileMap.isEmpty()){
                    for (String fileKey : multipartFileMap.keySet()) {
                        List<MultipartFile> fileList = multipartRequest.getFiles(fileKey);
                        for (MultipartFile mediaFile : fileList) {
                            String fileName = mediaFile.getOriginalFilename();
                            InputStream fileStream = mediaFile.getInputStream();
                            String uploadFileUrl = this.uploadFile(fileStream, fileName);
                            if ("".equals(uploadInfo)) {
                                uploadInfo = uploadFileUrl;
                            } else {
                                uploadInfo = uploadInfo + "," + uploadFileUrl;
                            }
                        }
                    }
                }
            }
            propertyInspectRecordPO.setUploadInfo(uploadInfo);
            iPropertyAppInspectServiceClient.saveInspectRecord(propertyInspectRecordPO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) propertyAppInspectDTO.getInspectId());
        } catch (Exception e) {
            throw new DataAccessException("【物业APP-首页提交巡检详情updateInspectPointDetail】提交巡检详情失败",e);
        }
    }

    /**
     * <desc>
     *      巡检记录月视图时间
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/02/17
     */
    @ResponseBody
    @PostMapping(path = "inspectRecordTime")
    public Object inspectRecordTime(HttpServletRequest request){
        try {
            PropertyAppInspectDTO propertyAppInspectDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAppInspectDTO.class, request);
            if (propertyAppInspectDTO == null || StringUtils.isBlank(propertyAppInspectDTO.getInspectPlanId()) || StringUtils.isBlank(propertyAppInspectDTO.getToken())
                    || StringUtils.isBlank(propertyAppInspectDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            PropertyUserCacheVO userCacheVO = iPropertyAppUserInfoServiceClient.retrieve(propertyAppInspectDTO.getToken());
            if (userCacheVO == null) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            propertyAppInspectDTO.setUserId(userCacheVO.getUserId());
            // 返回数据格式为年月和其对应的日期列表
            List<Map<String, Object>> data = iPropertyAppInspectServiceClient.getInspectRecordTime(propertyAppInspectDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【物业APP-首页巡检记录月视图时间inspectRecordTime】查询巡检记录月视图时间失败",e);
        }
    }

    /**
     * <desc>
     *      巡检记录月视图详情
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/02/17
     */
    @ResponseBody
    @PostMapping(path = "inspectRecordDetail")
    public Object inspectRecordDetail(HttpServletRequest request){
        try {
            PropertyAppInspectDTO propertyAppInspectDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAppInspectDTO.class, request);
            if (propertyAppInspectDTO == null || StringUtils.isBlank(propertyAppInspectDTO.getDay()) || StringUtils.isBlank(propertyAppInspectDTO.getToken())
                    || StringUtils.isBlank(propertyAppInspectDTO.getProjectId()) || StringUtils.isBlank(propertyAppInspectDTO.getInspectPlanId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            PropertyUserCacheVO userCacheVO = iPropertyAppUserInfoServiceClient.retrieve(propertyAppInspectDTO.getToken());
            if (userCacheVO == null) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            propertyAppInspectDTO.setUserId(userCacheVO.getUserId());
            List<PropertyAppInspectRecordDetailVO> propertyAppInspectRecordDetailVOList = iPropertyAppInspectServiceClient.getInspectRecordDetail(propertyAppInspectDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), propertyAppInspectRecordDetailVOList);
        } catch (Exception e) {
            throw new DataAccessException("【物业APP-首页巡检记录月视图详情inspectRecordDetail】查询巡检记录月视图详情失败",e);
        }
    }

    /**
     * <desc>
     *      分页获取巡检线路列表
     * </desc>
     *
     * @param inspectPlanId 巡检计划id
     * @param pageNum 页码
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2020/4/1
     */
    @ResponseBody
    @RequestMapping(value = "/getInspectList",method = RequestMethod.POST)
    public Object getInspectList(String inspectPlanId,String pageNum, String projectId,HttpServletRequest request){
        try{
            inspectPlanId = request.getAttribute("inspectPlanId") == null ? null : request.getAttribute("inspectPlanId").toString();
            pageNum = request.getAttribute("pageNum") == null ? null : request.getAttribute("pageNum").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isBlank(inspectPlanId) || StringUtils.isBlank(pageNum) || StringUtils.isBlank(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<PropertyAppInspectLineInfoVO> propertyAppInspectLineInfoVOS = iPropertyAppInspectServiceClient.getInspectLineList(inspectPlanId, projectId, pageNum);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),propertyAppInspectLineInfoVOS);
        }catch (Exception e){
            throw new DataAccessException("【物业app_首页_获取巡检线路列表getInspectList】获取巡检路线失败",e);
        }
    }

    /**
     * <desc>
     *      获取所有巡检点信息
     * </desc>
     *
     * @param projectId 项目id
     * @param pageNum 页码
     * @param inspectPlanId 巡检计划id
     * @return
     * @Author Zhu.yj
     * @createDate  2020/4/2
     */
    @RequestMapping(value = "/getAllInspectPointList",method = RequestMethod.POST)
    public Object getAllInspectPointList(String projectId, String pageNum,String inspectPlanId,HttpServletRequest request){
        try {
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            pageNum = request.getAttribute("pageNum") == null ? null : request.getAttribute("pageNum").toString();
            inspectPlanId = request.getAttribute("inspectPlanId") == null ? null : request.getAttribute("inspectPlanId").toString();
            if (StringUtils.isBlank(inspectPlanId) || StringUtils.isBlank(pageNum) || StringUtils.isBlank(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<String> inspectPointList = iPropertyAppInspectServiceClient.getInspectPointList(inspectPlanId, projectId, pageNum);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),inspectPointList);
        }catch (Exception e){
            throw new DataAccessException("【物业app_首页_获取所有巡检点信息getAllInspectPointList】获取所有巡检点信息失败",e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2020/01/08
     */
    private String uploadFile(InputStream inputStream, String fileName) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.INSPECT_UPLOAD_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean) resultMap.get("returnCode");
        if (!returnCode) {
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }
}
